//@author A0094511L
///@class GUI
///@Description This class is used to display the Main Window that is used by BOT
///				This class only contains logic that is related to the display of GUI
///				This class controls the signal emitted by UI, that is sent to Bot, the
///				the brain of BOT, and also allows feedback from Bot back to the UI by capturing
///				these signals through slots

#ifndef GUI_H
#define GUI_H

#include <QtWidgets/QMainWindow>
#include <QApplication>
#include "GeneratedFiles/ui_gui.h"
#include <QString>
#include <QMessageBox>
#include <QShortcut>
#include <QtCore>
#include <QtGui>
#include <QCompleter>
#include <QString>
#include <QAbstractTableModel>
#include <QSystemTrayIcon>
#include <QMenu>
#include <QxtGlobalShortcut>
#include <QGraphicsDropShadowEffect>
#include <QTimer>
#include <QDateTime>
#include <QListView>
#include <QScrollbar>
#include <QToolBar>
#include <cstring>

#include "botlogic.h"
#include "CommonUtils.h"
#include "lineedit.h"
#include "syntaxhighlighter.h"
#include "OutputManager.h"


class GUI : public QMainWindow{
	Q_OBJECT

public:
	GUI(QWidget *parent = 0);
	~GUI();

private:
	
	Ui::GUIClass ui;

	//@brief GUI is initialized by calling all setUp functions to set GUI components
	void initializeGUI();

	//@brief Function connects the signals with slots 
	void setUpConnections();

	//@brief Function sets up all keyboard shortcuts
	void setUpKeyBoardShortCuts();

	//@brief Function sets up loads up all the image files for the use of GUI
	void setUpAllImageFiles();

	//@brief Function sets up clock to reflect current date and time
	void setUpClock();

	//@brief Function sets up the style sheet of calendar using HTML
	void setCalendarStyle();
	
	//@brief Function sets up the style of calendar's navigation bar
	void setCalendarNavBarStyle();

	//@brief Function sets up the style of the current date in Calendar
	void setCalendarCurrentDayStyle();

	//@brief Function to set labels on the side bar. These labels sets their texts to the number of overdue, today, all, tasks
	///		 and event items, and are displayed next to their respective buttons to provide feedback for users.
	void setLabel();

	//@brief Function initialize all variables to be used
	void setUpVariables();

	//@brief Function sets up the system tray for use
	void setUpSystemTray();

	//@brief Function sets the shadow graphic effects for the GUI's widgets
	void setUpShadowGraphics();

	//@brief Function sets the animation for the appearing and disappearing for the use of Help Box
	void setUpAnimations();

	//@brief Function sets up the font color of the statusBar.
	void setUpStatusBar();

	//@brief Function creates the system tray icon
	void createSystemTrayIcon();
	
	//@brief Function creates Global Shortcut, which is used to maximize and minimize the application with a hotkey
	void createGlobalShortcut();
	
	//@brief Function upon initialization, calculates the no. of events and tasks for today, and displays in system tray
	void initRemindersForToday();
	
	//@brief Function reset all the buttons in the sidebar, overdue, today, all, event, tasks button to the unselected color
	void resetAllButtonColors();

	//@brief Function takes in the structure returnStatus and converts 
	///		 1. returnMsg to HTML using OutputManager for display in GUI
	///		 2. sets StatusMsg to statusBar for feedback to user
	void feedOutputToDisplay(CommonEnum::ReturnStatus);

	//@brief Function consists of other functions that is required to updated the GUI on the entering of userCommands
	void updateGUIWithNewOutput(CommonEnum::ReturnStatus);
	
	//@brief Function initalizes all buttons to be of correct color upon first load of GUI
	void initButtons();

	//@brief Function initalizes output box to display default display
	void initDisplay();

	//@brief Funtion sets up the basic settings of 3 Widgets
	//		 1. Set HelpBox to invisible
	//		 2. Set OutputBox to read only
	//		 3. Set FormatChecker to show the cross image initially
	void setMiscWidgetSettings();
	
	//@brief Function changes color of button based on the user command line input, to feedback to user what view user is in.
	void selectButtonFromCommandInput(string);

	//@brief Function sets up command Input to be in focus, and sets the syntaxHighlighter to start checking command input
	void setUpCommandInput();
	
	//@brief Function to receive help command from command line signal. A separate function is used
	//		 as the output is displayed in a separate box
	//@post  Returns True if the command is a help command, false otherwise
	bool receiveandValidateHelpCommand(string);	

	//@brief Function sets up completer by initializing the model to be used by the completer, and setting up the pointer to the completer
	void setUpCompleter();

	//@brief Function sets up the regular expressions to be used by receive help command
	void setRegExp();

	//@brief Function returns the help output to be displayed in HTML, based on the type of help command passed in
	QString helpTopics(QString);



	//Private data members

	BotLogic& _botControl;

	bool _isHelpDisplayed;
	
	int _thingsOverdue;
	int _thingsToday;

	int _formatCheckerLabelHeight;
	int _formatCheckerLabelWidth;

	QColor _currentDayColor;
	
	QCompleter*_comp;
	
	QGraphicsDropShadowEffect* _shadowEffectOutputBox;
	QGraphicsDropShadowEffect* _shadowEffectNewLabel;
	QGraphicsDropShadowEffect* _shadowEffectClashLabel;

	QPalette _statusBarPalette;
	
	QPixmap* _tickLabel;
	QPixmap* _crossLabel;
	QPixmap* overduePix;

	QPropertyAnimation* _enterAnimation;
	QPropertyAnimation* _exitAnimation;

	QString _className;

	QStringListModel* _stringListModel;
	QStringList _allNames;

	QSystemTrayIcon* _trayIcon;

	QTimer* _timer;
	
	QxtGlobalShortcut* _globalShortcut;
	
	SyntaxHighlighter* _highlighter;

	QRegExp _helpOverallFormat;
	QRegExp _helpAddFormat;
	QRegExp _helpDisplayFormat;
	QRegExp _helpDeleteFormat;
	QRegExp _helpEditFormat;
	QRegExp _helpSearchFormat;
	QRegExp _helpUndoFormat;
	QRegExp _helpRedoFormat;
	QRegExp _helpClearFormat;
	QRegExp _helpDateFormat;
	QRegExp _helpTimeFormat;
	QRegExp _helpDoneFormat;
	QRegExp _helpExitFormat;


	//static constants

	static const QString COMMAND_HELP_OVERALL;
	static const QString COMMAND_HELP_ADD;
	static const QString COMMAND_HELP_DISPLAY;
	static const QString COMMAND_HELP_DELETE;
	static const QString COMMAND_HELP_EDIT;
	static const QString COMMAND_HELP_SEARCH;
	static const QString COMMAND_HELP_UNDO;
	static const QString COMMAND_HELP_REDO;
	static const QString COMMAND_HELP_CLEAR;
	static const QString COMMAND_HELP_DATE;
	static const QString COMMAND_HELP_TIME;
	static const QString COMMAND_HELP_DONE;
	static const QString COMMAND_HELP_EXIT;

	static const QString HELP_DISPLAY_OVERALL;
	static const QString HELP_DISPLAY_ADD; 
	static const QString HELP_DISPLAY_DISPLAY; 
	static const QString HELP_DISPLAY_DELETE; 
	static const QString HELP_DISPLAY_EDIT; 
	static const QString HELP_DISPLAY_SEARCH; 
	static const QString HELP_DISPLAY_UNDO; 
	static const QString HELP_DISPLAY_REDO;
	static const QString HELP_DISPLAY_CLEAR; 
	static const QString HELP_DISPLAY_DATE; 
	static const QString HELP_DISPLAY_TIME; 
	static const QString HELP_DONE;
	static const QString HELP_EXIT;

	static const QString TEXT_PLACEHOLDER;
	static const QString COUNT_ZERO;
	static const QString COLOR_WINDOWS_BACKGROUND;
	
	static const QString FILENAME_TICK_PIXMAP;
	static const QString FILENAME_CROSS_PIXMAP;	
	
	static const QString NAME_CALENDAR_NAV_BAR;
	static const QString CALENDAR_NAV_BAR_COLOR;

	static const QString SUGGESTION_DEFAULT_DISPLAY;
	static const QString SUGGESTION_ADD;
	static const QString SUGGESTION_DELETE;
	static const QString SUGGESTION_DISPLAY;
	static const QString SUGGESTION_CLEAR;
	static const QString SUGGESTION_EDIT;
	static const QString SUGGESTION_SEARCH;
	static const QString SUGGESTION_UNDO;
	static const QString SUGGESTION_REDO;
	static const QString SUGGESTION_HELP;
	static const QString SUGGESTION_EXIT;

	static const QString SUGGESTION_CHAR_HINT_ADD;
	static const QString SUGGESTION_CHAR_HINT_DELETE;
	static const QString SUGGESTION_CHAR_HINT_DISPLAY;
	static const QString SUGGESTION_CHAR_HINT_CLEAR;
	static const QString SUGGESTION_CHAR_HINT_EDIT;
	static const QString SUGGESTION_CHAR_HINT_SEARCH;
	static const QString SUGGESTION_CHAR_HINT_UNDO;
	static const QString SUGGESTION_CHAR_HINT_REDO;
	static const QString SUGGESTION_CHAR_HINT_HELP;
	static const QString SUGGESTION_CHAR_HINT_EXIT;

	static const QString COLOR_SELECTED_BUTTON;
	static const QString COLOR_DESELECTED_BUTTON;

	static const QString ANCHOR_TODAY_HEADER;
	static const QString ANCHOR_NEW_ITEM;
	
	static const QString SYSTEM_TRAY_OPTION_SHOW;
	static const QString SYSTEM_TRAY_OPTION_CLOSE;

	static const QString FILENAME_SPLASHSCREEN;
	static const QString CLOCK_DATE_FORMAT;
	static const QString CLOCK_TIME_FORMAT;
	static const QString CALENDAR_DATE_FORMAT;

	static const int BUFFER_SIZE;
	static const char* STRING_REMINDER_NORMAL;
	static const char* STRING_REMINDER_OVERDUE;
	static const QString SYSTEM_TRAY_MESSAGE_TITLE;

	static const QString REGEX_SEARCH_KEYWORD;

	static const QString MSG_VALID_HELP_ENTERED;

private slots:

	//@brief Slot to receive command line signal from user from custom LineEdit
	void receiveCommand();
	
	//@brief slot to receive instruction to display suggestions based on user input
	void displaySuggestions();
	
	//@brief Slot to receive signal from user, when user types. This slot is for the format checker in GUI
	//		 If the current input is valid from the user, changes the cross label to a tick label
	void validCommandInput();
	
	//@brief Slot to receive undo shortcut when Command Input is not in focus, i.e. when somewhere else in the GUI is clicked for example
	void undoCalled();

	//@brief Slot to receive undo shortcut when command input is in focus, i.e. use undo shortcut with cursor in command input.
	void undoFromCommandInput();
	
	//@brief Slot to receive redo shortcut when Command Input is not in focus, i.e. when somewhere else in the GUI is clicked for example
	void redoCalled();

	//@brief Slot to receive redo shortcut when command input is in focus, i.e. use redo shortcut with cursor in command input.
	void redoFromCommandInput();

	//@brief Slot to receive signal when calendar date is double clicked by user
	void displayCalendarDate(const QDate&);
	
	//@brief Slot to receive signal when user clicks on the system tray.
	//@param reason refers to which of the options in the tray icon is chosen
	void trayIconClicked(QSystemTrayIcon::ActivationReason reason);
	
	//@brief Slot to receive signal when quit is called from System Tray
	void quitCmd();
	
	//@brief slot to receive instruction to toggle Visibility of the GUI window
	void toggleVisibility();
	
	//@brief Slot to receive signal to show current time
	void showTime();

	//@brief Slot to filter current output display when overdue button is clicked
	void filterOverduefromClick();

	//@brief Slot to filter current output display when today button is clicked
	void filterTodayfromClick();

	//@brief Slot to filter current output display when all button is clicked
	void filterAllfromClick();
	
	//@brief Slot to filter current output display when events button is clicked
	void filterEventsfromClick();

	//@brief Slot to filter current output display when tasks button is clicked
	void filterTasksfromClick();

	//@brief Slot to receive signal of up arrow when cursor is in command input, ie. command input is in focus
	void scrollup();

	//@brief Slot to receive signal of down arrow when cursor is in command input, ie. command input is in focus
	void scrolldown();

	//@brief Slot to set the completer to suggest words baed on data that we have for users and autoComplete 
	///		 if the words are chosen when search command is used
	void setCompleterWhenSearchCalled();

};


#endif // GUI_H
